<?php
class QueryBuilder
{
	/*
	*createCommand() - delete old query array
	*select() - create SELECT query command
	*from() - create FROM query command
	*where() - create WHERE query command
	*insert() - create INSERT query command
	*field() - create fields query for INSERT command
	*values - create VALUES query command
	*update() - create UPDATE query command
	*set() - create SET query command (for UPDATE)
	*delete() - create DELETE query command
	*limit() - create LIMIT query command
	*echoQuery() - print_r QUERY
	*getQuery() - get QUERY array in STRING type
	*/


	protected $query = array();
	protected $joinI;
	//Create newcommand
	//Unset old query
	public function createCommand()
	{
		if(isset($this->query))
		{
			unset($this->query);
		}
		return $this;
	}

	//Create SELECT command
	//select('id,name,email') - SELECT `id`,`name`,`email`
	//select(array('id','name','email')) - SELECT `id`,`name`,`email`
	public function select($columns='*')
	{
		$this->query['select'] = 'SELECT ';
		
		if(is_string($columns) && $columns != '*')
		{
			if(!strpos($columns,','))
			{
				$this->query['select'] .= '`'.$columns.'`';
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode('`,`',$columns);
				$columns = '`'.$columns.'`';
				$this->query['select'] .= $columns;
			}
		}
		elseif(is_array($columns))
		{
			$columns = implode('`,`',$columns);
			$columns = '`'.$columns.'`';
			$this->query['select'] .= $columns;
		}
		elseif($columns == '*')
		{
			$this->query['select'] .= '*';
		}
		else
		{
			throw new Exception('Incorrect data for SELECT.');
		}

		if(strpos($this->query['select'],'.'))
		{
			$this->query['select'] = str_replace('.','`.`',$this->query['select']);
		}	
		return $this;
	}

	public function whereS($columns)
	{
		$this->query['where'] = 'WHERE '. $columns;
		return $this;
	}

	//Create SELECT command
	//select('id,name,email') - SELECT `id`,`name`,`email`
	//select(array('id','name','email')) - SELECT `id`,`name`,`email`
	public function selectAs($columns='*')
	{
		$this->query['select'] = 'SELECT ';
		
		if(is_string($columns) && $columns!= '*')
		{
			if(!strpos($columns,','))
			{
				$this->query['select'] .= $columns;
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode(',',$columns);
				$columns = $columns;
				$this->query['select'] .= $columns;
			}
		}
		
		else
		{
			throw new Exception('Incorrect data for SELECT.');
		}

		return $this;
	}

	//Create FROM command
	//from('tableA,tableB') - FROM `tableA`, `tableB`
	//from(array('tableA','tableB')) - FROM `tableA`, `tableB`
	public function from($columns)
	{
		$this->query['from'] = 'FROM ';
		if(is_string($columns))
		{
			if(!strpos($columns,','))
			{
				$this->query['from'] .= '`'.$columns.'`';
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode('`,`',$columns);
				$columns = '`'.$columns.'`';
				$this->query['from'] .= $columns;
			}
		}
		elseif(is_array($columns))
		{
			$columns = implode('`,`',$columns);
			$columns = '`'.$columns.'`';
			$this->query['from'] .= $columns;
		}
		else
		{
			throw new Exception('Incorrect data for FROM.');
		}
		return $this;
	}

	public function whereGroup($columns)
	{
		$this->query['where'] = " WHERE ".$columns;
		return $this;
	}
	//Create WHERE command
	//where(id=2 AND name=sergey) - WHERE id=2 AND name=sergey
	//where(array('email','email@email.email')) - WHERE `email`='email@email.email'
	//where(array('or','sername','ivanov')) - OR `sername`='ivanov'
	public function where($columns)
	{
		if(empty($this->query['where']) && 
		   empty($this->query['whereGroup']) && 
		   empty($this->query['between']))
		{
			$this->query['where'] = 'WHERE ';
		}
		else
		{
			if(is_array($columns))
			{
				if($columns[0] == 'and')
				{
					$this->query['where'] .= ' AND ';
					unset($columns[0]);
				} 
				elseif($columns[0] == 'or')
				{
					$this->query['where'] .= ' OR ';
					unset($columns[0]);
				}
				else
				{
					$this->query['where'] .= ' AND ';
				}
			}
			
			if(strpos($this->query['where'],'.'))
			{
				$this->query['where'] = str_replace('.','`.`',$this->query['where']);
			}
		}
		if(is_string($columns))
		{
			$this->query['where'] .= $columns; 
		}
		elseif(is_array($columns))
		{
			if(isset($columns['3']))
			{
				switch($columns['3'])
				{
					case '>':
						unset($columns['3']);
						$columns = implode('`>\'',$columns);
						$columns = '`'.$columns.'\'';
						$this->query['where'] .= $columns;
						break;
					
					case '<>':
						if(!isset($columns[4]))
						{
							unset($columns['3']);
							$columns = implode('`<>\'',$columns);
							$columns = '`'.$columns.'\'';
							$this->query['where'] .= $columns;
							break;
						}
						elseif(isset($columns[4]))
						{
							if($columns[4] == '()')
							{
								unset($columns[3]);
								unset($columns[4]);
								$columns = implode('`<>\'',$columns);
								$columns = '(`'.$columns.'\')';
								$this->query['where'] .= $columns;
								break;
							}
						}
					
					case '()':
						unset($columns['3']);
						$columns = implode('`=\'',$columns);
						$columns = '(`'.$columns.'\')';
						$this->query['where'] .= $columns;
						break;	
						
						
				}	
			}
			else
			{
				$columns = implode('`=\'',$columns);
				$columns = '`'.$columns.'\'';
				$this->query['where'] .= $columns;
			}	
		}
		if(strpos($this->query['where'],'.'))
		{
			$this->query['where'] = str_replace('.','`.`',$this->query['where']);
		}
		return $this;
	}

	//Create INSERT INTO command
	//insert('table') - INSERT INTO `table`
	public function insert($columns)
	{
		$this->query['insert'] = 'INSERT INTO ';
		if(is_string($columns))
		{
			$this->query['insert'] .= '`'.$columns.'`'; 
		}
		else
		{
			throw new Exception('Incorrect data for INSERT.');
		}
		return $this;
	}

	//Create command for INSERT fields
	//field('name,email') - (`name`,`email`)
	//field(array('name','email')) - (`name`,`email`)
	public function field($columns)
	{
		if(is_string($columns))
		{
			if(!strpos($columns,','))
			{
				$this->query['field'] = '(`'.$columns.'`)';
			}
			elseif(strpos($columns,','))
			{
				$columns = explode(',',$columns);
				$this->query['field'] = '(`'.implode('`,`',$columns).'`)';
			}	
		}
		elseif(is_array($columns))
		{
			throw new Exception('JUST DO IT =)');
		}
		else
		{
			throw new Exception ('Incorrect data for FIELD.');
		}
		
		return $this;
	}

	//Create VALUES command
	//values('id,name,email') - VALUES('id','name','email')
	public function values($columns)
	{
		$this->query['values'] = 'VALUES ';
		if(is_string($columns))
		{
			if(!strpos($columns,','))
			{
				$this->query['values'] .= '(\''.$columns.'\')';
			}
			elseif(strpos($columns,','))
			{
				$columns = explode(',',$columns);
				$this->query['values'] .= '(\''.implode('\',\'',$columns).'\')';
			}
		}
		elseif(is_array($columns))
		{
			throw new Exception('JUST DO IT =)');
		}
		return $this;
	}

	//Create UPDATE command
	//update('table') - UPDATE `table`
	public function update($columns)
	{
		if(is_string($columns))
		{
			$this->query['update'] = 'UPDATE `'.$columns.'`';
		}
		else
		{
			throw new Exception('Incorrect data for UPDATE.');
		}
		return $this;
	}

	//Create command SET for UPDATE
	//set(array('name'=>'sergey','email'=>'sergey@gmail.com')) - SET `name` = 'sergey',`email` = 'sergey@gmail.com'
	public function set($columns)
	{
		if(is_array($columns))
		{
			if(empty($this->query['set']))
			{
				$this->query['set'] = ' SET ';
			}	
			$i = 0;
			foreach($columns as $field=>$value)
			{
				$i++;
				if($i == 1)
				{
					$this->query['set'] .= '`'.$field.'`'.' = '.'\''.$value.'\'';
				}
				else
				{
					$this->query['set'] .= ','.'`'.$field.'`'.' = '.'\''.$value.'\'';	
				}				
			}
		}
		return $this;
	}

	//Create DELETE command
	//delete('table') - DELETE FROM `table`
	public function delete($columns)
	{
		if(is_string($columns))
		{
			$this->query['delete'] = 'DELETE FROM `'.$columns.'`';
		}
		else
		{
			throw new Exception('Incorrect data for DELETE.');
		}
		
		return $this;
	}

	//Create LIMIT command
	//only integer type
	public function limit($columns)
	{
		if(is_integer($columns))
		{
			$this->query['limit'] = " LIMIT ";
			$this->query['limit'] .= $columns;
		}
		else
		{
			throw new Exception ('Incorrect data about LIMIT.');
		}
		return $this;
	}

	//Create where between command
	//between(array('time','12','24')) = Where `time` BETWEEN '12' AND '24'
	public function between($columns)
	{
		if(empty($this->query['where']))
		{
			if(is_array($columns))
			{
				$this->query['where'] = ' WHERE ';
				$this->query['where'] .= '`'.$columns[0].'`';
				$this->query['where'] .= ' BETWEEN ';
				$this->query['where'] .= '\''.$columns[1].'\'';
				$this->query['where'] .= ' AND ';
				$this->query['where'] .= '\''.$columns[2].'\'';
			}
			else
			{
				throw new Exception('Incorrect data for WHERE-BETWEEN command');
			}
		}
		else
		{
			if(is_array($columns))
			{
				if($columns[0] == 'and')
				{
					$this->query['where'] .= ' AND ';
					unset($columns[0]);
				} 
				elseif($columns[0] == 'or')
				{
					$this->query['where'] .= ' || ';
					unset($columns[0]);
				}
				else
				{
					$this->query['where'] .= ' AND ';
				}
			}
			
			if(is_array($columns))
			{
				if(!isset($columns[4]))
				{
					$this->query['where'] .= '`'.$columns[1].'`';
					$this->query['where'] .= ' BETWEEN ';
					$this->query['where'] .= '\''.$columns[2].'\'';
					$this->query['where'] .= ' AND ';
					$this->query['where'] .= '\''.$columns[3].'\'';
				}
				elseif(isset($columns[4]) && $columns[4] == 'reverse')
				{
					$this->query['where'] .= '\''.$columns[1].'\'';
					$this->query['where'] .= ' BETWEEN ';
					$this->query['where'] .= '`'.$columns[2].'`';
					$this->query['where'] .= ' AND ';
					$this->query['where'] .= '`'.$columns[3].'`';
				}
			}
			else
			{
				throw new Exception('Incorrect data for WHERE-BETWEEN command');
			}
			
			if(strpos($this->query['where'],'.'))
			{
				$this->query['where'] = str_replace('.','`.`',$this->query['where']);
			}
		}
		return $this;
	}
	
	//Print_r array with all QUERY COMMAND
	public function echoQuery()
	{
		if(!empty($this->query))
		{
			echo '<pre>';
			print_r($this->query);
			echo '</pre>';
		}
		else
		{
			throw new Exception('There is no information about QUERY.');
		}
	}

	//Create command for JOIN
	public function join($columns)
	{
		$this->joinI++;
		$this->query['join'.$this->joinI] = 'JOIN ';
		if(is_string($columns))
		{
			if(!strpos($columns,','))
			{
				$this->query['join'.$this->joinI] .= '`'.$columns.'`';
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode('`,`',$columns);
				$columns = '`'.$columns.'`';
				$this->query['join'.$this->joinI] .= $columns;
			}
		}
		elseif(is_array($columns))
		{
			$columns = implode('`,`',$columns);
			$columns = '`'.$columns.'`';
			$this->query['join'.$this->joinI] .= $columns;
		}
		else
		{
			throw new Exception('Incorrect data for JOIN.');
		}
		return $this;
	}

	//Create command for LEFT JOIN
	public function leftJoin($columns)
	{
		$this->leftJoinI++;
		$this->query['leftJoin'.$this->leftJoinI] = 'LEFT JOIN ';
		if(is_string($columns))
		{
			if(!strpos($columns,','))
			{
				$this->query['leftJoin'.$this->leftJoinI] .= '`'.$columns.'`';
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode('`,`',$columns);
				$columns = '`'.$columns.'`';
				$this->query['leftJoin'.$this->leftJoinI] .= $columns;
			}
		}
		elseif(is_array($columns))
		{
			$columns = implode('`,`',$columns);
			$columns = '`'.$columns.'`';
			$this->query['leftJoin'.$this->leftJoinI] .= $columns;
		}
		else
		{
			throw new Exception('Incorrect data for LEFTJOIN.');
		}
		return $this;
	}

	//Create command ON for JOIN
	public function on($columns)
	{
		$this->query['on'] = 'ON ';
		
		if(is_string($columns))
		{
			if(!strpos($columns,','))
			{
				$this->query['on'] .= '`'.$columns.'`';
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode('`=`',$columns);
				$columns = '`'.$columns.'`';
				$this->query['on'] .= $columns;
			}
		}
		elseif(is_array($columns))
		{
			$columns = implode('`,`',$columns);
			$columns = '`'.$columns.'`';
			$this->query['on'] .= $columns;
		}
		else
		{
			throw new Exception('Incorrect data for ON.');
		}

		if(strpos($this->query['on'],'.'))
		{
			$this->query['on'] = str_replace('.','`.`',$this->query['on']);
		}	
		return $this;
	}

	public function group($columns)
	{
		$this->query['group'] = 'GROUP BY';
		if(is_string($columns) && $columns!= '*')
		{
			if(!strpos($columns,','))
			{
				$this->query['group'] .= '`'.$columns.'`';
			}
			elseif(strpos($columns, ','))
			{
				$columns = explode(',',$columns);
				$columns = implode('`,`',$columns);
				$columns = '`'.$columns.'`';
				$this->query['group'] .= $columns;
			}
		}
		elseif(is_array($columns))
		{
			$columns = implode('`,`',$columns);
			$columns = '`'.$columns.'`';
			$this->query['group'] .= $columns;
		}
		elseif($columns == '*')
		{
			$this->query['group'] .= '*';
		}
		else
		{
			throw new Exception('Incorrect data for GROUP.');
		}
		if(strpos($this->query['group'],'.'))
		{
			$this->query['group'] = str_replace('.','`.`',$this->query['group']);
		}	
		return $this;
	}

	//Return QUERY string from query array
	public function getQuery()
	{
		if(isset($this->query) && !empty($this->query))
		{
			return implode(' ',$this->query);	
		}
	}
}
